﻿// -----------------------------------------------------------------------
// <copyright company="Christoph van der Fecht - VDsoft">
// Copyright (C) Christoph van der Fecht - VDsoft - All Rights Reserved
// Unauthorized copying of this file, via any medium is strictly prohibited,
// unless it is communicated and authorized by the copyright owner.
// </copyright>
// -----------------------------------------------------------------------

using SeriesManager.ViewModel.Options;
using System.Collections.Generic;
using Ninject;
using TVDB.Web;

namespace SeriesManager.ViewModel
{
	/// <summary>
	/// Locator that holds all available vew models.
	/// </summary>
	public class ViewModelLocator
	{
		/// <summary>
		/// Ninject kernel.
		/// </summary>
		private static IKernel kernel = null;

		/// <summary>
		/// Api key for the application.
		/// </summary>
		private readonly string apiKey = "CE1AECDA14314FD5";

		/// <summary>
		/// Name of the banner options dialog.
		/// </summary>
		private const string BannerOptionsName = "BannerOptions";

		/// <summary>
		/// Initializes a new instance of the <see cref="ViewModelLocator"/> class.
		/// </summary>
		public ViewModelLocator()
		{
			this.SetupNinject();
		}

		/// <summary>
		/// Gets the current instance of the <see cref="MainViewModel"/> class.
		/// </summary>
		public static MainViewModel MainView
		{
			get
			{
				return GetInstance<MainViewModel>();
			}
		}

		/// <summary>
		/// Gets the current instance of the <see cref="SearchSeriesViewModel"/> class.
		/// </summary>
		public static SearchSeriesViewModel SearchSeriesView
		{
			get
			{
				return GetInstance<SearchSeriesViewModel>();
			}
		}

		/// <summary>
		/// Gets the current instance of the <see cref="EpisodeManagerViewModel"/> class.
		/// </summary>
		public static EpisodeManagerViewModel EpisodeManagerView
		{
			get
			{
				return GetInstance<EpisodeManagerViewModel>();
			}
		}

		/// <summary>
		/// Gets the current instance of the <see cref="BannerManagerViewModel"/> class.
		/// </summary>
		public static BannerManagerViewModel BannerManagerView
		{
			get
			{
				return GetInstance<BannerManagerViewModel>();
			}
		}

		/// <summary>
		/// Gets the current instance of the <see cref="AboutDialogViewModel"/> class.
		/// </summary>
		public static AboutDialogViewModel AboutDialogView
		{
 			get
			{
				return GetInstance<AboutDialogViewModel>();
			}
		}

		/// <summary>
		/// Gets the current instance of the <see cref="ActorsViewModel"/> class.
		/// </summary>
		public static ActorsViewModel ActorView
		{
			get
			{
				return GetInstance<ActorsViewModel>();
			}
		}

		#region Tokens

		/// <summary>
		/// Token search series messages.
		/// </summary>
		public static object SearchSeriesToken = new object();

		/// <summary>
		/// Token for all details of a series.
		/// </summary>
		public static object SeriesDetailsToken = new object();

		/// <summary>
		/// Token for all banner details of a series.
		/// </summary>
		public static object SeriesBannerToken = new object();

		/// <summary>
		/// Token for all actors details of a series.
		/// </summary>
		public static object SeriesActorToken = new object();

		#endregion

		#region option dialogs

		public static Dictionary<string, OptionsPart> Options = new Dictionary<string, OptionsPart>();

		/// <summary>
		/// Gets the current instance of the <see cref="BannerSettingsViewModel"/> class.
		/// </summary>
		public static BannerSettingsViewModel BannerSettings
		{
			get
			{
				if (!Options.ContainsKey(BannerOptionsName))
				{
					Options.Add(BannerOptionsName, GetInstance<BannerSettingsViewModel>());
				}

				return (BannerSettingsViewModel)Options[BannerOptionsName];
			}
		}

		/// <summary>
		/// Gets the current instance of the <see cref="OptionsDialogViewModle"/> class.
		/// </summary>
		public static OptionsDialogViewModle OptionDialog
		{
			get
			{
				return GetInstance<OptionsDialogViewModle>();
			}
		}

		#endregion

		/// <summary>
		/// Gets the instance of the provided type.
		/// </summary>
		/// <typeparam name="T">Type of which the instance was requested.</typeparam>
		/// <returns>The instance of the requested type.</returns>
		public static T GetInstance<T>()
		{
			return kernel.Get<T>();
		}

		/// <summary>
		/// Setup for ninject.
		/// </summary>
		private void SetupNinject()
		{
			kernel = new StandardKernel();

			// tvdb interface
			kernel.Bind<ITvDb>()
				.To<WebInterface>()
				.InSingletonScope()
				.WithConstructorArgument("apiKey", this.apiKey);

			// view models
			// main View
			kernel.Bind<MainViewModel>()
				.To<MainViewModel>()
				.InSingletonScope();

			// search view
			kernel.Bind<SearchSeriesViewModel>()
				.To<SearchSeriesViewModel>()
				.InSingletonScope();

			// episode manager view
			kernel.Bind<EpisodeManagerViewModel>()
				.To<EpisodeManagerViewModel>()
				.InSingletonScope();

			// banner manager view
			kernel.Bind<BannerManagerViewModel>()
				.To<BannerManagerViewModel>()
				.InSingletonScope();

			// about dialog
			kernel.Bind<AboutDialogViewModel>()
				.To<AboutDialogViewModel>()
				.InSingletonScope();

			// actors view
			kernel.Bind<ActorsViewModel>()
				.To<ActorsViewModel>()
				.InSingletonScope();

			// options

			// banner settings
			kernel.Bind<BannerSettingsViewModel>()
				.To<BannerSettingsViewModel>()
				.InSingletonScope();

			// options dialog
			kernel.Bind<OptionsDialogViewModle>()
				.To<OptionsDialogViewModle>()
				.InSingletonScope();
		}
	}
}
